package plus.easydo.starter.oauth.resources.aspect;

import cn.hutool.core.lang.Validator;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import plus.easydo.core.exception.ExceptionFactory;
import plus.easydo.starter.oauth.core.utils.Oauth2Utils;
import plus.easydo.starter.oauth.resources.anotation.CustomizePreAuthorize;
import plus.easydo.starter.oauth.resources.service.MySecurityExpressionRoot;

import java.lang.reflect.Method;

/**
 * 自定义权限实现
 *
 * @author yuzhanfeng
 */
@Aspect
@Component
public class CustomizePreAuthorizeAspect {

    /**
     * 数组为0时
     */
    private static final Integer ARRAY_EMPTY = 0;

    /**
     * @param point  切点
     * @return 结果
     * @throws Throwable HasPermissionException
     */
    @Around("@annotation(plus.easydo.starter.oauth.resources.anotation.CustomizePreAuthorize)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        CustomizePreAuthorize annotation = method.getAnnotation(CustomizePreAuthorize.class);
        if (annotation == null) {
            return point.proceed();
        }
        Authentication authentication = Oauth2Utils.getOauth2Authentication();
        MySecurityExpressionRoot expressionRoot = new MySecurityExpressionRoot(authentication);
        if (ARRAY_EMPTY < annotation.hasPermission().length) {
            if (!expressionRoot.hasAnyPermission(annotation.hasPermission())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (ARRAY_EMPTY < annotation.notHasPermission().length) {
            if (expressionRoot.hasAnyPermission(annotation.notHasPermission())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (ARRAY_EMPTY < annotation.hasScope().length) {
            if (!expressionRoot.hasAnyScope(annotation.hasScope())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (ARRAY_EMPTY < annotation.notHasScope().length) {
            if (expressionRoot.hasAnyScope(annotation.notHasScope())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (Validator.isNotEmpty(annotation.hasClient())) {
            if (!expressionRoot.hasClient(annotation.hasClient())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (Validator.isNotEmpty(annotation.notHasClient())) {
            if (expressionRoot.hasClient(annotation.notHasClient())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (ARRAY_EMPTY < annotation.hasResource().length) {
            if (!expressionRoot.hasAnyResource(annotation.hasResource())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (ARRAY_EMPTY < annotation.notHasResource().length) {
            if (expressionRoot.hasAnyResource(annotation.notHasResource())) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (annotation.read()) {
            if (!expressionRoot.read()) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (annotation.write()) {
            if (!expressionRoot.write()) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (annotation.create()) {
            if (!expressionRoot.create()) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (annotation.delete()) {
            if (!expressionRoot.delete()) {
                throw ExceptionFactory.hasPermissionException();
            }
        } else if (annotation.all()) {
            if (expressionRoot.all()) {
                return point.proceed();
            }
            throw ExceptionFactory.hasPermissionException();
        }
        return point.proceed();
    }


}
